<template>
  <n-space class="Users" vertical>
    <n-space justify="space-between">
      <n-button @click="createUser"> 添加新用户 </n-button>
      <n-form
        ref="formRef"
        inline
        :label-width="80"
        :model="formValue"
        label-placement="left"
        :rules="rules"
      >
        <n-form-item label="账号" path="account">
          <n-input v-model:value="formValue.account" />
        </n-form-item>
        <n-form-item label="昵称" path="nickname">
          <n-input v-model:value="formValue.nickname" />
        </n-form-item>
        <n-form-item label="邮箱" path="email">
          <n-input v-model:value="formValue.email" />
        </n-form-item>
        <n-form-item label="身份" path="status">
          <n-select
            v-model:value="formValue.role"
            clearable
            :options="roleOptions"
          />
        </n-form-item>
        <n-form-item>
          <n-button @click="findClick"> 查询 </n-button>
        </n-form-item>
      </n-form>
    </n-space>
    <n-data-table
      :columns="columns"
      :data="data"
      :pagination="pagination"
      :bordered="false"
      remote
      :row-key="rowKey"
      @update:page-size="handlePageSizeChange"
      @update:page="handlePageChange"
    />
  </n-space>
  <Dialog :title="editData ? '编辑用户' : '新增用户'" v-model:show="dialogShow">
    <n-form
      ref="dialogFormRef"
      :label-width="80"
      label-align="left"
      :model="dialogFormValue"
      label-placement="left"
      :rules="dialogRules"
    >
      <n-form-item label="账号" path="account">
        <n-input
          v-model:value="dialogFormValue.account"
          placeholder="输入账号"
        />
      </n-form-item>
      <n-form-item label="昵称" path="nickname">
        <n-input
          v-model:value="dialogFormValue.nickname"
          placeholder="输入账号"
        />
      </n-form-item>
      <n-form-item label="邮箱" path="email">
        <n-input v-model:value="dialogFormValue.email" placeholder="输入账号" />
      </n-form-item>
      <n-form-item label="身份" path="status">
        <n-select
          v-model:value="dialogFormValue.role"
          clearable
          :options="roleOptions"
        />
      </n-form-item>
      <n-form-item>
        <n-button @click="clickUser"> 保存 </n-button>
      </n-form-item>
    </n-form>
  </Dialog>
</template>

<script setup lang="ts">
import {
  type FormInst,
  type FormItemRule,
  NForm,
  NFormItem,
  NInput,
  NButton,
  NSelect,
  NSpace,
  NDataTable,
  NTag,
  type SelectOption,
  type SelectGroupOption,
  type DataTableColumns,
  NImage,
} from "naive-ui";
import {
  roleOptions,
  findAll as apiUsersFindAll,
  updateOne as apiUsersUpdate,
  createUser as apiUsersCreate,
  resetPassword as apiUsersResetPassword,
  type Users,
  UserRole,
} from "~/api/user";
useHead({
  title: "用户管理", //网站标题
});

definePageMeta({
  title: "用户管理",
});

const dialogShow = ref(false);
const editData = ref("");
const dialogFormValue = ref<{
  account: string;
  nickname: string;
  email: string;
  role: string | null;
}>({
  account: "",
  nickname: "",
  email: "",
  role: null,
});

const dialogFormRef = ref<FormInst | null>();
const clickUser = async (e: MouseEvent) => {
  e.preventDefault();
  const messageReactive = naiveui.message.loading("Verifying", {
    duration: 0,
  });
  dialogFormRef.value?.validate(async (errors) => {
    if (!errors) {
      if (editData.value) {
        // 修改
        const res = await apiUsersUpdate(editData.value, {
          ...dialogFormValue.value,
          role: dialogFormValue.value.role ?? UserRole.visitor,
        });
        if (res.code === 0) {
          dialogShow.value = false;
          findUserList();
        }
      } else {
        // 新增
        const res = await apiUsersCreate({
          ...dialogFormValue.value,
          password: "123456",
        });
        if (res.code === 0) {
          dialogShow.value = false;
          findUserList();
        }
      }
    } else {
      naiveui.message.error(errors[0][0].message ?? "表单验证错误");
    }
    messageReactive.destroy();
  });
};
const createUser = async () => {
  editData.value = "";
  dialogShow.value = true;
  dialogFormValue.value = {
    account: "",
    nickname: "",
    email: "",
    role: null,
  };
};

const dialogRules = {
  account: [
    {
      required: true,
      message: "请输入账号",
      trigger: "blur",
    },
    {
      pattern: /^([a-zA-Z0-9]){8,16}$/,
      message: "用户账号长度大于8,小于16、且不允许特殊字符",
      trigger: "blur",
    },
  ],
  nickname: [
    {
      required: true,
      message: "请输入昵称",
      trigger: "blur",
    },
    {
      min: 1,
      max: 5,
      message: "长度大于1小于5",
      trigger: "blur",
    },
  ],
  email: [
    {
      pattern: /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,
      message: "不符合邮箱格式",
      trigger: "blur",
    },
  ],
};

const formRef = ref<FormInst | null>();
const formValue = ref({
  account: "",
  nickname: "",
  email: "",
  role: null,
});
const rules = {
  name: {
    pattern: /^.{0,10}$/,
    message: "查询长度小于10",
    trigger: "input",
  },
  path: {
    pattern: /^.{0,10}$/,
    message: "查询长度小于10",
    trigger: "input",
  },
};

const findClick = (e: MouseEvent) => {
  e.preventDefault();
  const messageReactive = naiveui.message.loading("Verifying", {
    duration: 0,
  });
  formRef.value?.validate(async (errors) => {
    if (!errors) {
      findUserList();
    } else {
      naiveui.message.error(errors[0][0].message ?? "表单验证错误");
    }
    messageReactive.destroy();
  });
};

const dayjs = useDayjs();
const createColumns = ({
  edit,
  resetPassword,
}: {
  edit: (row: Users) => void;
  resetPassword: (row: Users) => void;
}): DataTableColumns<Users> => {
  return [
    {
      title: "账号",
      key: "account",
    },
    {
      title: "昵称",
      key: "nickname",
    },
    {
      title: "头像",
      key: "avatar",
      render(row) {
        return h(NImage, {
          width: "50",
          src: row.avatar,
        });
      },
    },
    {
      title: "邮件",
      key: "email",
    },
    {
      title: "身份",
      key: "role",
      render(row) {
        const role = roleOptions.find((item) => item.value == row.role);
        return role?.label;
      },
    },
    {
      title: "Action",
      key: "actions",
      render(row: Users) {
        const editAction = h(
          NButton,
          {
            strong: true,
            tertiary: true,
            size: "small",
            style: {
              margin: "0px 5px",
            },
            onClick: () => edit(row),
          },
          { default: () => "编辑" }
        );
        const resetPasswordAction = h(
          NButton,
          {
            strong: true,
            tertiary: true,
            size: "small",
            style: {
              margin: "0px 5px",
            },
            onClick: () => resetPassword(row),
          },
          { default: () => "密码重置" }
        );
        return [editAction, resetPasswordAction];
      },
    },
  ];
};

const data = ref<Users[]>([]);

const columns = createColumns({
  async edit(row: Users) {
    editData.value = row.id;
    dialogShow.value = true;
    dialogFormValue.value = {
      account: row.account,
      nickname: row.nickname,
      email: row.email,
      role: row.role,
    };
  },
  async resetPassword(row: Users) {
    await apiUsersResetPassword(row.id);
  },
});
const rowKey = (rowData: { id: any }) => {
  return rowData.id;
};
const handlePageChange = (page: number) => {
  pagination.value.page = page;
  findUserList();
};
const handlePageSizeChange = (pageSize: number) => {
  pagination.value.pageSize = pageSize;
  pagination.value.page = 1;
  findUserList();
};
const pagination = ref({
  page: 1,
  pageSize: 10,
  itemCount: 0,
  showSizePicker: true,
  pageSizes: [3, 5, 7],
});
const findUserList = async () => {
  const res = await apiUsersFindAll({
    ...formValue.value,
    pageNum: pagination.value.page,
    pageSize: pagination.value.pageSize,
  });
  if (res.data) {
    data.value = res.data.list;
    pagination.value.itemCount = res.data.count;
  }
};
onMounted(async () => {
  
  findUserList();
});
</script>
<style lang="scss" scoped>
.Users {
  
  padding: 20px 15px;
  .n-input,
  .n-select {
    width: 200px;
  }
  .n-pagination {
    justify-content: center;
  }
}
</style>
